package info.wangyuan.agent.service.curd.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import info.wangyuan.agent.assembler.ModelConfigAssembler;
import info.wangyuan.agent.common.Constant.AgentConstant;
import info.wangyuan.agent.common.Constant.ModelConstant;
import info.wangyuan.agent.common.Enum.ModelType;
import info.wangyuan.agent.entity.po.*;
import info.wangyuan.agent.entity.vo.CurrentModelConfigVO;
import info.wangyuan.agent.exception.BusinessException;
import info.wangyuan.agent.mapper.*;
import info.wangyuan.agent.service.curd.CommonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 公共服务实现类
 * 避免Service产生循环依赖
 *
 * @author Albert
 * @since 2025-07-22 19:15:30
 */
@Slf4j
@Service
public class CommonServiceImpl implements CommonService {


    private final PromptMapper promptMapper;
    private final KnowledgeBaseMapper kbMapper;
    private final FileInfoMapper fileInfoMapper;
    private final KnowledgeSourceMapper ksMapper;
    private final ModelConfigMapper modelConfigMapper;
    private final AgentConfigMapper agentConfigMapper;
    private final DocumentUnitMapper documentUnitMapper;

    public CommonServiceImpl(PromptMapper promptMapper, KnowledgeBaseMapper kbMapper, FileInfoMapper fileInfoMapper, KnowledgeSourceMapper ksMapper, ModelConfigMapper modelConfigMapper, AgentConfigMapper agentConfigMapper, DocumentUnitMapper documentUnitMapper) {
        this.promptMapper = promptMapper;
        this.kbMapper = kbMapper;
        this.fileInfoMapper = fileInfoMapper;
        this.ksMapper = ksMapper;
        this.modelConfigMapper = modelConfigMapper;
        this.agentConfigMapper = agentConfigMapper;
        this.documentUnitMapper = documentUnitMapper;
    }

    /**
     * 获取当前欢迎语
     */
    @Override
    public String getCurrentWelcomeMsg() {
        AgentConfig agentConfig = agentConfigMapper.selectOne(
                Wrappers.lambdaQuery(AgentConfig.class)
                        .eq(AgentConfig::getEnabled, AgentConstant.ON)
        );
        if (agentConfig == null) return "您好，欢迎向我提问";
        return agentConfig.getWelcomeMessage();
    }

    /**
     * 获取当前模型配置
     */
    @Override
    public CurrentModelConfigVO getCurrentModelConfig() {
        ModelConfig config = modelConfigMapper.selectOne(
                Wrappers.lambdaQuery(ModelConfig.class)
                        .eq(ModelConfig::getType, ModelType.LLM.getValue())
                        .eq(ModelConfig::getStatus, ModelConstant.IS_ACTIVE)
        );
        if (config == null)
            throw new BusinessException("配置异常，当前模型丢失");
        return ModelConfigAssembler.toVO(config);
    }

    /**
     * 检查模型是否存在
     */
    @Override
    public void checkModelIfNotExist(Integer id, String type) {
        ModelConfig dbModel = modelConfigMapper.selectById(id);
        if (dbModel == null) {
            if (Objects.equals(type, ModelType.LLM.getValue()))
                throw new BusinessException("对话模型不存在");
            else if (Objects.equals(type, ModelType.TEXT_EMBEDDING.getValue()))
                throw new BusinessException("嵌入模型不存在");
            else if (Objects.equals(type, ModelType.RERANK.getValue()))
                throw new BusinessException("重排序模型不存在");
            else if (Objects.equals(type, ModelType.OCR.getValue()))
                throw new BusinessException("OCR模型不存在");
        }
    }

    /**
     * 检查提示词模版是否存在
     */
    @Override
    public void checkPromptIfNotExist(Integer id) {
        SystemPrompts prompts = promptMapper.selectById(id);
        if (prompts == null)
            throw new BusinessException("提示词模版不存在");
    }

    /**
     * 检查智能体是否存在
     */
    @Override
    public void checkAgentIfNotExist(Integer id) {
        AgentConfig dbAgent = agentConfigMapper.selectById(id);
        if (dbAgent == null)
            throw new BusinessException("智能体不存在");
    }

    /**
     * 激活模型
     */
    @Override
    public void activeModel(Integer id, String type) {
        this.checkModelIfNotExist(id, type);
        ModelConfig dbModel = modelConfigMapper.selectById(id);
        modelConfigMapper.update(Wrappers.lambdaUpdate(ModelConfig.class)
                .set(ModelConfig::getStatus, ModelConstant.IS_NOT_ACTIVE)
                .eq(ModelConfig::getType, type));
        dbModel.setStatus(ModelConstant.IS_ACTIVE);
        modelConfigMapper.updateById(dbModel);
    }

    /**
     * 根据单个 Agent ID 查询其绑定的知识库名称列表
     */
    @Override
    public List<String> getKnowledgeBaseNamesByAgentId(Integer agentId) {
        List<KnowledgeSource> knowledgeSources = ksMapper.selectList(
                Wrappers.lambdaQuery(KnowledgeSource.class)
                        .eq(KnowledgeSource::getAgentId, agentId)
        );

        if (CollUtil.isEmpty(knowledgeSources))
            return Collections.emptyList();

        List<Integer> kbIds = knowledgeSources.stream()
                .map(KnowledgeSource::getKnowledgeBaseId)
                .distinct()
                .collect(Collectors.toList());

        List<KnowledgeBase> knowledgeBases = kbMapper.selectByIds(kbIds);
        return knowledgeBases.stream()
                .map(KnowledgeBase::getName)
                .collect(Collectors.toList());
    }

    /**
     * 批量查询多个 Agent ID 对应的知识库映射
     */
    @Override
    public Map<Integer, List<String>> getKnowledgeBaseNamesForAgents(Set<Integer> agentIds) {
        if (CollUtil.isEmpty(agentIds))
            return Collections.emptyMap();

        List<KnowledgeSource> kss = ksMapper.selectList(
                Wrappers.lambdaQuery(KnowledgeSource.class)
                        .in(KnowledgeSource::getAgentId, agentIds)
        );

        if (CollUtil.isEmpty(kss))
            return Collections.emptyMap();

        // 批量查询所有涉及的知识库
        List<Integer> kbIds = kss.stream()
                .map(KnowledgeSource::getKnowledgeBaseId)
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, String> kbIdNameMap = kbMapper.selectByIds(kbIds)
                .stream()
                .collect(Collectors.toMap(KnowledgeBase::getId, KnowledgeBase::getName));

        // 按 agentId 分组
        var agentKnowledgeMap = new HashMap<Integer, List<String>>();
        for (KnowledgeSource ks : kss) {
            String kbName = kbIdNameMap.getOrDefault(ks.getKnowledgeBaseId(), "未知知识库");
            agentKnowledgeMap
                    .computeIfAbsent(ks.getAgentId(), k -> new ArrayList<>())
                    .add(kbName);
        }

        return agentKnowledgeMap;
    }

    /**
     * 根据知识库ID删除知识源
     *
     * @param kbId 知识库ID
     */
    @Override
    public void deleteKnowledgeSource(Integer kbId) {
        ksMapper.delete(Wrappers.lambdaQuery(KnowledgeSource.class).eq(KnowledgeSource::getKnowledgeBaseId, kbId));
    }

    /**
     * 根据知识库ID批量查询KnowledgeBase
     *
     * @param kbIds 知识库ID集合
     * @return List<KnowledgeBase>
     */
    @Override
    public List<KnowledgeBase> getKbs(Set<Integer> kbIds) {
        return kbMapper.selectByIds(kbIds);
    }

    /**
     * 根据文件ID批量删除文件信息
     *
     * @param fileIds 文件ID集合
     */
    @Override
    public void deleteFileInfosByFileIds(List<Integer> fileIds) {
        if (CollUtil.isEmpty(fileIds)) return;
        fileInfoMapper.deleteByIds(fileIds);
    }

    /**
     * 根据文件ID批量删除文件单元
     *
     * @param fileIds 文件ID集合
     */
    @Override
    public void deleteDocUnitsByFileIds(List<Integer> fileIds) {
        if (CollUtil.isEmpty(fileIds)) return;
        documentUnitMapper.delete(Wrappers.lambdaQuery(DocumentUnit.class).in(DocumentUnit::getFileId, fileIds));
    }

}
